﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Xml.Serialization;

[XmlRoot()]
public class Reseau
{
    [XmlElement()]
    public List<Couche> liste;

    public Reseau(int[] nombreNeuroneParCouche, double alpha)
    {
        liste = new List<Couche>();

        for (int i = 0; i <= nombreNeuroneParCouche.Length - 1; i++)
        {
            if (i == 0)
            {
                liste.Add(new Couche(nombreNeuroneParCouche[0], 1, alpha));
            }
            else
            {
                liste.Add(new Couche(nombreNeuroneParCouche[i], nombreNeuroneParCouche[i - 1], alpha));
            }
        }
    }

    public Reseau()
    {
    }

    public Perceptron getPerceptron(int indiceCouche, int indicePerceptron)
    {
        return liste[indiceCouche].getPerceptron(indicePerceptron);
    }

    public void insertData(double[] data)
    {
        for (int i = 1; i <= data.Length; i++)
        {
            Perceptron temp = liste[0].getPerceptron(i - 1);
            temp.getSortie = data[i - 1];

        }
    }

    public void loadNextLayer(int indiceNextLayer)
    {
        Couche cCurrent = liste[indiceNextLayer - 1];
        Couche cNext = liste[indiceNextLayer];
        for (int i = 1; i <= cCurrent.size(); i++)
        {
            Perceptron pCurrent = cCurrent.getPerceptron(i - 1);
            for (int j = 1; j <= cNext.size(); j++)
            {
                Perceptron pNext = cNext.getPerceptron(j - 1);
                pNext.setEntree(i, pCurrent.getSortie);
            }
        }
    }

    public void calculErreur(int indiceN, double cible)
    {
        Perceptron p = liste[liste.Count - 1].getPerceptron(indiceN);
        p.getErreur = p.getSortie - cible;
    }

    public void calculErreur(int indiceN, int indiceC)
    {
        Perceptron p = liste[indiceC].getPerceptron(indiceN);
        double erreur = 0;
        for (int i = 0; i <= liste[indiceC + 1].size() - 1; i++)
        {
            Perceptron temp = liste[indiceC + 1].getPerceptron(i);
            erreur = erreur + temp.getErreur * temp.getPoids(indiceN);
        }
        erreur = erreur * Perceptron.activation(p.getPotentiel, 1) * (1 - Perceptron.activation(p.getPotentiel, 1));
        p.getErreur = erreur;

    }

    public double sigmaErreur()
    {
        double retour = 0;
        for (int i = 0; i <= liste[liste.Count - 1].size(); i++)
        {
            Perceptron p = liste[liste.Count - 2].getPerceptron(i);
            retour = retour + Math.Abs(p.getErreur);

        }
        return retour;
    }

    public Couche getC(int indice)
    {
        return liste[indice];
    }

}